/***********************************************************************
 * Module:  Controleur.java
 * Author:  Fabien Muguet
 * Purpose: Defines the Class Controleur
 ***********************************************************************/

package controleur;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.util.Date;
import java.util.Vector;
import javax.imageio.ImageIO;
import modele.*;
import modele.ZoneImage;
import vue.*;

/**
 * Controlleur de l'application. Gère les actions utilisateurs.
 * @author Administrateur
 */
public class Controleur {

   private Ressources ressources;
   private FenetreMere fenetreMere;


   /**
    * A la construction, on créer les ressouces et les vues puis on les initialise.
    */
   public Controleur() {

       // Création du modèle
       ressources = new Ressources();

       // Pour débug
//       debugInitRessources();

       // Création des vues
       fenetreMere = new FenetreMere(this, ressources);

       // Chargement des ressources et initialisation des vues
       initialiser();

       // Démarrage de l'application
       fenetreMere.setVisible(true);

       // Pour débug
       fenetreMere.afficherEcran("accueil");


   }

   /**
    * Initialise les ressources et les vues
    */
   public void initialiser() {

       // Création d'une carte postale vierge
       ressources.initialiser();

       // On initialise toutes les vues
       fenetreMere.initialiser();

   }


   /**
    * Pour débug.
    */
   public void debugInitRessources() {

        // Création d'un mdl en dur
        ZoneTexte zTexte = new ZoneTexte(380, 512, 50, 32);
        ZoneImage[] zImages = new ZoneImage[3];
        zImages[0] = new ZoneImage(10, 10, 300, 400, 0);
        zImages[1] = new ZoneImage(320, 10, 430, 300, 0);
        zImages[2] = new ZoneImage(10, 530, 740, 484, 0);
        ModeleCarte testModele = new ModeleCarte(ModeleCarte.Orientation.PORTRAIT, zTexte, zImages);

        // Ajout 5 fois à la liste des mdl
        Vector<ModeleCarte> vmc = new Vector<ModeleCarte>();
        for(int i=0; i < 5; i++)
            vmc.add(testModele);
        ressources.setModeles(vmc);

        // Ajout de 5 images importées
        try {
             BufferedImage import1BI = ImageIO.read( getClass().getResource("/imports/import1.jpg") );
             Image import1 = new Image("chemin", "import1", new Date(2010, 5, 31), import1BI);
             BufferedImage import2BI = ImageIO.read( getClass().getResource("/imports/import2.jpg") );
             Image import2 = new Image("chemin", "import2", new Date(2010, 5, 31), import2BI);
             BufferedImage import3BI = ImageIO.read( getClass().getResource("/imports/import3.jpg") );
             Image import3 = new Image("chemin", "import3", new Date(2010, 5, 31), import3BI);
             BufferedImage import4BI = ImageIO.read( getClass().getResource("/imports/import4.jpg") );
             Image import4 = new Image("chemin", "import4", new Date(2010, 5, 31), import4BI);

             import1.creerMiniature( new Dimension(201, 150) );
             import1.enregistrerEnMemoire();
             import2.creerMiniature( new Dimension(201, 150) );
             import2.enregistrerEnMemoire();
             import3.creerMiniature( new Dimension(201, 150) );
             import3.enregistrerEnMemoire();
             import4.creerMiniature( new Dimension(201, 150) );
             import4.enregistrerEnMemoire();

             Vector<Image> vimg = new Vector<Image>();
             vimg.add(import1); vimg.add(import2); vimg.add(import3); vimg.add(import4);

             ressources.setImagesImportees(vimg);
        }
        catch(Exception ex) {
            System.out.println("PB DEBUG chargement des ressouces.");
        }

        // Nouvelle carte postale
        ressources.setCartePostale( new CartePostale(testModele) );

        // Image sur zone
        ressources.setImageSurZone(
                new ImageSurZone(
                    ressources.getImagesImportees().get(0),
                    ressources.getCartePostale().getModele().getZoneImage()[0]
                )
        );
   }



   /**
    * Appelé lors d'un clic sur un bouton "Recommencer" de l'application.
    * Réinitialise les données et retour à l'écran d'accueil.
    */
   public void trRecommencer() {
       ressources.initialiser();
       fenetreMere.afficherEcran("accueil");
   }

   /**
    * Appelé lors d'un clic sur "Commencer" de l'écran EcranAccueil.
    */
   public void trAccueilSuivant() {
      fenetreMere.afficherEcran("modele");
   }

   /**
   * Appelé lors d'un clic sur "Précédent" de l'écran EcranModele.
   */
   public void trModelePrecedent() {
      fenetreMere.afficherEcran("accueil");
   }

   /**
    * Appelé lors d'un clic sur "Suivant" de l'écran EcranModele.
    */
   public void trModeleSuivant() throws Exception {

       // On récupère le modele selectionné dans la vue
       ModeleCarte modele = fenetreMere.getEcranModele().getModeleSelectionne();

       // Si la vue est bien codée, on ne devrait jamais entrer dans ce bloc
       if( modele == null ) {
            System.out.println("[ERREUR] Aucun modele selectionne dans la vue EcranModele.");
            throw new Exception("Aucun modele selectionne dans la vue EcranModele.");
       }

       // On enregistre le modele choisi comme modèle pour la carte postale
       ressources.getCartePostale().setModele(modele);

       // On passe à l'écran suivant
       fenetreMere.afficherEcran("fond");

   }

   /**
    * Appelé lors d'un clic sur "Précedent" de l'écran EcranFond.
    */
   public void trFondPrecedent() {
        fenetreMere.afficherEcran("modele");
   }

   /**
    * Appelé lors d'un clic sur "Suivant" de l'écran EcranFond.
    */
   public void trFondSuivant() {

       EcranFond ec = fenetreMere.getEcranFond();
       CartePostale cp = ressources.getCartePostale();

       // On a choisi une image de fond
       if( ec.isChoixEstImage() ) {
           cp.setCouleurDeFond( Color.WHITE );
           cp.setImageDeFond( ec.getImageChoisie() );
       } else {
           cp.setImageDeFond( null );
           cp.setCouleurDeFond( ec.getCouleurChoisie() );
       }

       // On passe à l'écran suivant
       fenetreMere.afficherEcran("import");
   }

   /**
    * Appelé lors d'un clic sur "Précedent" de l'écran EcranImport.
    */
   public void trImportPrecedent() {
      fenetreMere.afficherEcran("fond");
   }

   /**
    * Appelé lors d'un clic sur "Suivant" de l'écran EcranImport.
    */
   public void trImportSuivant() {

       // On récupère la référence
       EcranImport ei = fenetreMere.getEcranImport();

       // On récupère les images importées
       ressources.setImagesImportees( ei.getImagesImportees() );

       // On passe à la suite
       fenetreMere.afficherEcran("position");
   }

   /**
    * Appelé lorsque l'on clic sur Précédent de l'écran de positionnement
    */
   public void trPositionnementPrecedent() {

       // On doit enlever les images positionnées
       ressources.getCartePostale().setImagesSurZones( null );

       // On retourne en arrière
       fenetreMere.afficherEcran("import");
   }

   /**
    * Appelé lorsque le drag and drop est effectué dans l'écran Position
    */
   public void trPositionnementDND() throws Exception {

      // On récupère la référence vers l'écran
      EcranPosition ep = fenetreMere.getEcranPosition();

      // On tente de récupérer les infos du DND
      Image image = null;
      ZoneImage zoneImage = null;
      try {
           // Infos du glissés déposé
           image = ep.getImageDND();
           zoneImage = ep.getZoneImageDND();

           // L'image devrait être enregistrée en mémoire, on la restaure
           image.chargerDepuisMemoire();
      } catch(Exception ex) {
           System.out.println("[ERREUR] Probleme lors de la récupération des infos du drag and drop.");
           throw new Exception("Probleme lors de la récupération des infos du drag and drop.");
      }

      // On prépare l'info pour l'écran de retouche
      ImageSurZone imageSurZone = new ImageSurZone(image, zoneImage);
      ressources.setImageSurZone(imageSurZone);

      // On passe à l'écran de retouche
      fenetreMere.afficherEcran("retouche");

   }

   /**
    * Appelé lorsque toutes les images sont positionées et que l'on clic sur suivant
    */
   public void trPositionnementSuivant() {

       // Ici aucune action puisque l'enrichissement est déjà fait par l'écran retouche
       fenetreMere.afficherEcran("texte");

   }

   /**
    * Appelé lors d'une annulation de retouche d'image
    */
   public void trEffetAnnuler() {

       // L'image n'a plus besoin d'être en cache
       ressources.getImageSurZone().getImage().enregistrerEnMemoire();

       // Plus d'info de glissé-déposé
       ressources.setImageSurZone(null);

       // On retourne à l'écran de positionnement
       fenetreMere.afficherEcran("position");
   }

   /**
    * Appelé lors d'une validation de retouche d'image
    */
   public void trEffetValider() {

       // On récupère la référence vers l'écran
       EcranRetouche er = fenetreMere.getEcranRetouche();

       // On récupère l'image modifiée
       Image imageAvecEffet = er.getImageAvecEffets();

       // On récupère la zone de destination
       ZoneImage zoneDestination = ressources.getImageSurZone().getZone();

       // On enregistre l'image sur sa position
       CartePostale cartePostale = ressources.getCartePostale();
       int nbImgModele = cartePostale.getModele().getZoneImage().length;

       ImageSurZone[] imagesSurZones = cartePostale.getImagesSurZones();
       if( imagesSurZones == null ) {
           // Premier positionnement d'image sur une zone, on doit créer le tableau
           cartePostale.setImagesSurZones( new ImageSurZone[nbImgModele] );
           imagesSurZones = cartePostale.getImagesSurZones();
       }

       boolean trouve = false;
       for(int i = 0; i < imagesSurZones.length && !trouve; i++) {
           if( imagesSurZones[i] == null ) {
               imagesSurZones[i] = new ImageSurZone(imageAvecEffet, zoneDestination);
               trouve = true;
           }
       }

       // On garde une miniature et on met l'image en mémoire
       imageAvecEffet.creerMiniature( new Dimension(zoneDestination.getWidth(), zoneDestination.getHeight()) );
       imageAvecEffet.enregistrerEnMemoire();

       // L'image source n'a plus besoin d'être en cache
       ressources.getImageSurZone().getImage().enregistrerEnMemoire();

       // Enfin on retourne à l'écran de positionnement
       fenetreMere.afficherEcran("position");
   }

   /**
    * Appelé lors d'un clic sur "Précédent" de l'écran du texte perso.
    */
   public void trTextePrecedent() {

       // On retourne à l'écran de positionnement
       fenetreMere.afficherEcran("position");
   }

   /**
    * Appelé lors d'un clic sur "Suivant" de l'écran du texte perso.
    */
   public void trTexteSuivant() {
       
       // On récupère une référence vers l'écran
       EcranTexte et = fenetreMere.getEcranTexte();
       
       // On récupère le texte personnalisé
       TextePerso tp = et.getTextePerso();
       
       // On enregistre dans les ressources
       if( tp.getTexte().equals("<Votre texte ici>") )
            tp.setTexte("");
       ressources.getCartePostale().setTextePerso( tp );
       // On retourne à l'écran de positionnement
       fenetreMere.afficherEcran("impression");
   }

   /**
    * Appelé lors d'un clic sur "Imprimer" de l'écran d'impression
    */
   public void trImpressionImprimer(java.awt.Image imageFinale) {

       PrinterJob job = PrinterJob.getPrinterJob();

      // Définit son contenu à imprimer
      ImprimerCarte imprimerCarte = new ImprimerCarte();
      imprimerCarte.ImageAImprimer(imageFinale);
      job.setPrintable(imprimerCarte);

      // Affiche une boîte de choix d'imprimante
      if (job.printDialog()){
         try {
            // Effectue l'impression
            job.print();
         } catch (PrinterException ex) {
            ex.printStackTrace();
         }
      }
   }

   /**
    * Appelé lors d'un clic sur "Sauvergarder" de l'écran d'impression
    */
   public void trImpressionSauvegarder() {

       /*
        * Attention, le JFileChooser doit figurer dans l'écran.
        * Ici le Controleur va chercher l'image générée et la destination avec des getters.
        * Il procède ensuite à l'enregistrement
        */
   }

   /**
    * Appelé lors d'un clic sur "Terminer" de l'écran d'impression
    */
   public void trImpressionTerminer() {

       // On recommence un cycle
       trRecommencer();
   }

   /**
    * Appelé lors d'un clic sur "Précédent" de l'écran d'impression
    */
   public void trImpressionPrecedent() {

       // Retour à l'écran texte
       fenetreMere.afficherEcran("texte");
   }

}